package us.kg.kotoriforest.base;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Scanner;

public class TestPreparedStatement {
    public static void main(String[] args) throws Exception {
        // 自动注册驱动

        String url = "jdbc:mysql:///JDBC";
        String username = "root"; // 操作数据库的用户的用户名
        String password = "";
        Connection connection = DriverManager.getConnection(url, username, password);

        /*
         * PreparedStatement 是 Statement 的子接口
         * PreparedStatement 会将 SQL 语句进行预编译 所以效率高于 Statement 如果 SQL 语句会重复利用 那么效率还会高
         * PreparedStatement 应对 SQL 注入的方式是
         *   在将用户输入替换掉 ? 占位符后 会在两侧分别加上一个 ' 来将整个语句作为字符串
         *   如果本来就是字符串 就当字符串用
         *   如果不是字符串 MySQL 会在执行语句的时候进行隐式类型转换 如 "3.14" -> 3.14
         *   并且会将用户输入的特殊字符进行转义处理 ' -> \' 一定会将用户输入当成一个完整的整体
         * */
        PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM t_emp WHERE emp_name = ?");

        // 获取用户输入
        Scanner scanner = new Scanner(System.in);
        String emp_name = scanner.nextLine();
        scanner.close();

        // 将 preparedStatement SQL 语句中的 ? 占位符给替换掉
        // setXxx 系列函数的第一个参数是占位符的序号 从 1 开始 和 MySQL 相同
        preparedStatement.setString(1, emp_name);

        ResultSet resultSet = preparedStatement.executeQuery();

        while (resultSet.next()) {
            int empId = resultSet.getInt("emp_id");
            String empName = resultSet.getString("emp_name");
            double empSalary = resultSet.getDouble("emp_salary");
            int empAge = resultSet.getInt("emp_age");
            System.out.println(empId + "\t" + empName + "\t" + empSalary + "\t" + empAge);
        }

        // 由外到内关闭资源
        resultSet.close();
        preparedStatement.close();
        connection.close();
    }
}
